import re
from dataclasses import dataclass
from typing import List, Dict, Union, Optional


@dataclass
class DeviceInfo:
    dev_id: str
    dev_type: Optional[str]
    dev_name: str
    status_channels: List[int]


@dataclass
class LineInfo(DeviceInfo):
    voltage_channels: List[int]
    current_channels: List[int]
    length: str
    rx: List[float]
    bus_id: str


@dataclass
class BusInfo(DeviceInfo):
    rated_value: str
    ratio: str
    voltage_channels: List[int]


@dataclass
class TransformerInfo(DeviceInfo):
    capacity: str
    winding_num: int

    voltage_hv_channels: List[int]
    voltage_lv_channels: List[int]
    voltage_mv_channels: List[int]
    oth_status_channels: List[int]
    oth_achns: List[int]

    current_hv_channels: List[int]
    current_lv_channels: List[int]
    current_mv_channels: List[int]


class INFParser:
    """解析INF故障录波文件的解析器"""

    def __init__(self):
        self.lines: List[LineInfo] = []
        self.buses: List[BusInfo] = []
        self.transformers: List[TransformerInfo] = []
        self.file_info: Dict[str, Union[str, int, float]] = {}

    def parse_file(self, file_path: str) -> bool:
        """
        解析INF文件

        Args:
            file_path: INF文件路径

        Returns:
            bool: 解析是否成功
        """
        try:
            # 尝试多种编码
            encodings = ['gbk', 'gb2312', 'cp936']
            content = None

            for encoding in encodings:
                try:
                    with open(file_path, 'r', encoding=encoding, errors='ignore') as f:
                        content = f.read()
                    break
                except UnicodeDecodeError:
                    continue

            if content is None:
                print(f"无法读取文件，尝试了所有编码: {encodings}")
                return False

            return self.parse_content(content)
        except Exception as e:
            print(f"读取文件失败: {e}")
            return False

    def parse_content(self, content: str) -> bool:
        """
        解析INF文件内容

        Args:
            content: 文件内容字符串

        Returns:
            bool: 解析是否成功
        """
        try:
            # 清空之前的数据
            self.lines.clear()
            self.buses.clear()
            self.transformers.clear()

            self.file_info.clear()

            # 解析基本文件信息
            self._parse_file_description(content)

            # 解析所有设备的通道信息
            self._parse_all_devices(content)

            return True
        except Exception as e:
            print(f"解析内容失败: {e}")
            return False

    def _parse_file_description(self, content: str) -> None:
        """解析文件描述信息"""
        section_match = re.search(r'\[Public File_Description\](.*?)(?=\[|$)', content, re.DOTALL)
        if not section_match:
            return

        section_content = section_match.group(1)

        # 提取基本信息
        patterns = {
            'station_name': r'Station_Name=(.+)',
            'recording_device_id': r'Recording_Device_ID=(.+)',
            'total_channel_count': r'Total_Channel_Count=(\d+)',
            'trigger_time': r'Trigger_Time=(.+)',
        }

        for key, pattern in patterns.items():
            match = re.search(pattern, section_content)
            if match:
                value = match.group(1).strip()
                if key == 'total_channel_count':
                    try:
                        value = int(value)
                    except ValueError:
                        pass
                self.file_info[key] = value

    def _parse_all_devices(self, content: str) -> None:
        """解析所有设备信息"""
        # 定义设备类型模式
        device_patterns = [
            # 线路设备模式
            (r'\[(?:\w+\s+)?Line_#(\d+)\](.*?)(?=\[|$)', 'line'),
            (r'\[(?:\w+\s+)?Bus_#(\d+)\](.*?)(?=\[|$)', 'bus'),
            (r'\[(?:\w+\s+)?(?:Transformer|Trans|TRM)_#(\d+)\](.*?)(?=\[|$)', 'transformer'),
        ]

        for pattern, device_type in device_patterns:
            matches = re.findall(pattern, content, re.DOTALL | re.IGNORECASE)
            for device_num_str, section_content in matches:
                self._parse_device_channels(device_type, device_num_str, section_content)

    def _parse_device_channels(self, device_type: str, device_num: str, section_content: str) -> Optional[DeviceInfo]:
        """
        解析单个设备的通道信息

        Args:
            device_type: 设备类型
            device_num: 设备编号
            section_content: 设备section内容

        Returns:
            DeviceChannels: 设备通道信息，解析失败返回None
        """
        try:
            if device_type == 'line':
                self._parse_line_info(section_content)
            elif device_type == 'bus':
                self._parse_bus_info(section_content)
            elif device_type == 'transformer':
                self._parse_transformer_info(section_content)
            else:
                print(f"未知设备类型: {device_type}")
                return None

        except Exception as e:
            print(f"解析{device_type} #{device_num} 通道信息时出错: {e}")
            return None


    def _parse_line_info(self, section_content):
        device_id, device_name = self._extract_device_name(section_content)
        dev_type = self._extract_value(section_content, r'OBJECT_TYPE=(.+)')
        length = self._extract_value(section_content, r'LENGTH=(.+)')
        rx = [float(x) for x in self._extract_value(section_content, r'RX=(.+)').split(',')]
        ta_channels = [int(x) for x in self._extract_value(section_content, r'TA_CHNS=(.+)').split(',')]
        tv_channels = [int(x) for x in self._extract_value(section_content, r'TV_CHNS_#1=(.+)').split(',')]
        status_channels = self._extract_value(section_content, r'STATUS_CHNS=(.+)')
        bus_id = self._extract_value(section_content, r'BUS_ID_#1=(.+)')

        line = LineInfo(
            dev_id=device_id,
            dev_name=device_name,
            dev_type=dev_type,
            length=length,
            rx=rx,
            current_channels=ta_channels,
            voltage_channels=tv_channels,
            status_channels=[int(x) for x in status_channels.split(',')] if status_channels else [],
            bus_id=bus_id
        )

        self.lines.append(line)


    def _parse_bus_info(self, section_content):
        dev_id, dev_name = self._extract_device_name(section_content)
        rated_value = self._extract_value(section_content, r'RATED_VALUE=(.+)')
        ratio = self._extract_value(section_content, r'TV_RATIO=(.+)')
        tv_channels = [int(x) for x in self._extract_value(section_content, r'TV_CHNS=(.+)').split(',')]
        status_channels = self._extract_value(section_content, r'STATUS_CHNS=(.+)')

        bus = BusInfo(
            dev_id=dev_id,
            dev_name=dev_name,
            dev_type='bus',
            rated_value=rated_value,
            ratio=ratio,
            voltage_channels=tv_channels,
            status_channels=[int(x) for x in status_channels.split(',')] if status_channels else []
        )

        self.buses.append(bus)

    def _parse_transformer_info(self, section_content):
        dev_id, dev_name = self._extract_device_name(section_content)
        dev_type = self._extract_value(section_content, r'OBJECT_TYPE=(.+)')
        capacity = self._extract_value(section_content, r'CAPACITY=(.+)')
        winding_num = self._extract_value(section_content, r'WINDING_NUM=(.+)')
        high_voltage = self._extract_value(section_content, r'H_TV_CHNS=(.+)')
        high_current = self._extract_value(section_content, r'TA_Id_#1=(.+)').split(',')
        low_voltage = self._extract_value(section_content, r'L_TV_CHNS=(.+)')
        low_current = self._extract_value(section_content, r'TA_Id_#3=(.+)').split(',')
        mid_voltage = self._extract_value(section_content, r'M_TV_CHNS=(.+)')
        mid_current = self._extract_value(section_content, r'TA_Id_#5=(.+)').split(',')
        oth_achns = self._extract_value(section_content, r'OTH_ACHNS=(.+)').split(',')
        oth_status_channels = self._extract_value(section_content, r'OTH_STATUS_CHNS=(.+)').split(',')

        transformer = TransformerInfo(
            dev_id=dev_id,
            dev_name=dev_name,
            dev_type=dev_type,
            capacity=capacity,
            winding_num=winding_num,
            voltage_hv_channels=[int(chn) for chn in high_voltage.split(',')] if high_voltage else [],
            voltage_lv_channels=[int(chn) for chn in low_voltage.split(',')] if low_voltage else [],
            voltage_mv_channels=[int(chn) for chn in mid_voltage.split(',')] if mid_voltage else [],
            oth_achns=[int(x) for x in oth_achns] if oth_achns else [],
            oth_status_channels=[int(x) for x in oth_status_channels] if oth_status_channels else [],
            status_channels=[int(x) for x in oth_status_channels] if oth_status_channels else [],
            current_hv_channels=[int(x) for x in high_current if int(x) != 1] if high_current else [],
            current_lv_channels=[int(x) for x in low_current if int(x) != 1] if low_current else [],
            current_mv_channels=[int(x) for x in mid_current if int(x) != 1] if mid_current else []
        )

        self.transformers.append(transformer)


    def get_lines_data(self):
        return [line.__dict__ for line in self.lines]

    def get_buses_data(self):
        return [bus.__dict__ for bus in self.buses]

    def get_transformers_data(self):
        return [transformer.__dict__ for transformer in self.transformers]

    def print_summary(self):
        """
        打印解析后的设备信息摘要
        """
        print("=" * 50)
        print("INF文件解析摘要")
        print("=" * 50)
        
        # 打印文件基本信息
        print("\n[文件基本信息]")
        for key, value in self.file_info.items():
            print(f"  {key}: {value}")
        
        # 打印线路信息
        print(f"\n[线路信息] - 共{len(self.lines)}条线路")
        for i, line in enumerate(self.lines, 1):
            print(f"  线路{i}:")
            print(f"    ID: {line.dev_id}")
            print(f"    名称: {line.dev_name}")
            print(f"    类型: {line.dev_type}")
            print(f"    长度: {line.length}")
            print(f"    电流通道: {line.current_channels}")
            print(f"    电压通道: {line.voltage_channels}")
            print(f"    状态通道: {line.status_channels}")
            print(f"    母线ID: {line.bus_id}")
            print(f"    RX: {line.rx}")
        
        # 打印母线信息
        print(f"\n[母线信息] - 共{len(self.buses)}条母线")
        for i, bus in enumerate(self.buses, 1):
            print(f"  母线{i}:")
            print(f"    ID: {bus.dev_id}")
            print(f"    名称: {bus.dev_name}")
            print(f"    类型: {bus.dev_type}")
            print(f"    额定值: {bus.rated_value}")
            print(f"    变比: {bus.ratio}")
            print(f"    电压通道: {bus.voltage_channels}")
            print(f"    状态通道: {bus.status_channels}")
        
        # 打印变压器信息
        print(f"\n[变压器信息] - 共{len(self.transformers)}台变压器")
        for i, transformer in enumerate(self.transformers, 1):
            print(f"  变压器{i}:")
            print(f"    ID: {transformer.dev_id}")
            print(f"    名称: {transformer.dev_name}")
            print(f"    类型: {transformer.dev_type}")
            print(f"    容量: {transformer.capacity}")
            print(f"    绕组数: {transformer.winding_num}")
            print(f"    高压侧电压通道: {transformer.voltage_hv_channels}")
            print(f"    高压侧电流通道: {transformer.current_hv_channels}")
            print(f"    低压侧电压通道: {transformer.voltage_lv_channels}")
            print(f"    低压侧电流通道: {transformer.current_lv_channels}")
            print(f"    中压侧电压通道: {transformer.voltage_mv_channels}")
            print(f"    中压侧电流通道: {transformer.current_mv_channels}")
            print(f"    其他模拟通道: {transformer.oth_achns}")
            print(f"    其他状态通道: {transformer.oth_status_channels}")
            print(f"    状态通道: {transformer.status_channels}")

    @staticmethod
    def _extract_device_name(section_content):
        """提取设备名称"""
        match = re.search(r'DEV_ID=(\d+),(.+)', section_content)
        if match:
            device_id, device_name = match.groups()
            return device_id, device_name

        return ""

    @staticmethod
    def _extract_value(section_content, pattern):
        match = re.search(pattern, section_content)
        if match:
            return match.group(1)

        return ""


if __name__ == '__main__':
    inf_parser = INFParser()

    try:
        if inf_parser.parse_file('../data/2025-02-14_15-16-56_ACT_14576#录波装置.INF'):
            inf_parser.print_summary()

    except Exception as e:
        print(f"解析文件失败: {e}")
